#include "lcd_init.h"
#include "stdio.h"
#include <string.h>
// #include "app.h"
#define Command 0
#define Parameter 1
typedef void (*FunType)(void);
//**********************************write function begin********************************************
void wr_cmd_4spi_8bcs(uint8_t par)
{
    LCD_DCXLow();
    LCD_CSLow();

    LCD_SCLLow();
    if (par & 0x80)
        LCD_SDAHigh();
    else
        LCD_SDALow();
    LCD_SCLHigh();

    LCD_SCLLow();
    if (par & 0x40)
        LCD_SDAHigh();
    else
        LCD_SDALow();
    LCD_SCLHigh();

    LCD_SCLLow();
    if (par & 0x20)
        LCD_SDAHigh();
    else
        LCD_SDALow();
    LCD_SCLHigh();

    LCD_SCLLow();
    if (par & 0x10)
        LCD_SDAHigh();
    else
        LCD_SDALow();
    LCD_SCLHigh();

    LCD_SCLLow();
    if (par & 0x08)
        LCD_SDAHigh();
    else
        LCD_SDALow();
    LCD_SCLHigh();

    LCD_SCLLow();
    if (par & 0x04)
        LCD_SDAHigh();
    else
        LCD_SDALow();
    LCD_SCLHigh();

    LCD_SCLLow();
    if (par & 0x02)
        LCD_SDAHigh();
    else
        LCD_SDALow();
    LCD_SCLHigh();

    LCD_SCLLow();
    if (par & 0x01)
        LCD_SDAHigh();
    else
        LCD_SDALow();
    LCD_SCLHigh();

    LCD_CSHigh();
    LCD_DCXHigh();
    HAL_Delay(5);
}
void wr_dat_4spi_8bcs(uint8_t par)
{
    LCD_DCXHigh();
    LCD_CSLow();

    LCD_SCLLow();
    if (par & 0x80)
        LCD_SDAHigh();
    else
        LCD_SDALow();
    LCD_SCLHigh();

    LCD_SCLLow();
    if (par & 0x40)
        LCD_SDAHigh();
    else
        LCD_SDALow();
    LCD_SCLHigh();

    LCD_SCLLow();
    if (par & 0x20)
        LCD_SDAHigh();
    else
        LCD_SDALow();
    LCD_SCLHigh();

    LCD_SCLLow();
    if (par & 0x10)
        LCD_SDAHigh();
    else
        LCD_SDALow();
    LCD_SCLHigh();

    LCD_SCLLow();
    if (par & 0x08)
        LCD_SDAHigh();
    else
        LCD_SDALow();
    LCD_SCLHigh();

    LCD_SCLLow();
    if (par & 0x04)
        LCD_SDAHigh();
    else
        LCD_SDALow();
    LCD_SCLHigh();

    LCD_SCLLow();
    if (par & 0x02)
        LCD_SDAHigh();
    else
        LCD_SDALow();
    LCD_SCLHigh();

    LCD_SCLLow();
    if (par & 0x01)
        LCD_SDAHigh();
    else
        LCD_SDALow();
    LCD_SCLHigh();

    LCD_CSHigh();
    LCD_DCXHigh();
    HAL_Delay(1);
}
void wr_cmd_parall1_8(uint16_t par)
{
    LCD_DCXLow();
    LCD_CSLow();
    LCD_WRLow();
    GPIOB->ODR = par;

    LCD_WRHigh();
}
void wr_dat_parall1_8(uint16_t par)
{
    LCD_DCXHigh();
    LCD_WRLow();
    GPIOB->ODR = par;

    LCD_WRHigh();
}
void wr_cmd_parall1_16(uint16_t par)
{
    LCD_DCXLow();
    LCD_CSLow();
    LCD_WRLow();
    GPIOB->ODR = par;

    LCD_WRHigh();
}
void wr_dat_parall1_16(uint16_t par)
{
    LCD_DCXHigh();
    LCD_WRLow();
    GPIOB->ODR = par;

    LCD_WRHigh();
}
void wr_cmd_7775r(uint16_t par)
{
    uint8_t parH = par >> 6;
    uint32_t parL = (par << 10) & 0xFC00;
    LCD_DCXLow();
    LCD_CSLow();
    LCD_WRLow();
    if (parH & 0x02)
        HAL_GPIO_WritePin(DB17_GPIO_Port, DB17_Pin, GPIO_PIN_SET);
    else
        HAL_GPIO_WritePin(DB17_GPIO_Port, DB17_Pin, GPIO_PIN_RESET);

    if (parH & 0x01)
        HAL_GPIO_WritePin(DB16_GPIO_Port, DB16_Pin, GPIO_PIN_SET);
    else
        HAL_GPIO_WritePin(DB16_GPIO_Port, DB16_Pin, GPIO_PIN_RESET);

    GPIOB->ODR = parL;

    // LCD_WRHigh();
}

void wr_cmd_parall2_8(uint16_t par)
{
    LCD_DCXLow();
    LCD_CSLow();
    LCD_WRLow();
    GPIOB->ODR = par << 1;

    LCD_WRHigh();
}
void wr_dat_parall2_8(uint16_t par)
{
    LCD_DCXHigh();
    LCD_WRLow();
    GPIOB->ODR = par << 1;

    LCD_WRHigh();
}
//**********************************read function begin********************************************
void pb_out(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    // db 0-7
    GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 |
                          GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
void pb_in(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    // db 0-7
    GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 |
                          GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
uint8_t i801_read_byte(void)
{
    uint8_t v;

    LCD_DCXHigh();
    LCD_RDLow();
    v = GPIOB->IDR;
    LCD_RDHigh();

    return v;
}
void rd_parall1_8(uint8_t c, uint8_t *d, uint32_t l)
{
    uint8_t buf[128];

    wr_cmd_parall1_8(c);
    pb_in();
    for (int i = 0; i < l; i++)
    {
        buf[i] = i801_read_byte();
    }
    LCD_CSHigh();
    pb_out();
    memcpy(d, buf, l);
}
//**********************************write display begin********************************************
void wr_displ_parall1_8(uint8_t color)
{
    LCD_DCXHigh();
    LCD_WRLow();
    GPIOB->ODR = color;
    LCD_WRHigh();
}
void wr_displ_parall2_18(uint16_t color1, uint16_t color2)
{
    LCD_DCXHigh();
    LCD_WRLow();
    if (color1 & 0x02)
        HAL_GPIO_WritePin(DB17_GPIO_Port, DB17_Pin, GPIO_PIN_SET);
    else
        HAL_GPIO_WritePin(DB17_GPIO_Port, DB17_Pin, GPIO_PIN_RESET);
    if (color1 & 0x01)
        HAL_GPIO_WritePin(DB16_GPIO_Port, DB16_Pin, GPIO_PIN_SET);
    else
        HAL_GPIO_WritePin(DB16_GPIO_Port, DB16_Pin, GPIO_PIN_RESET);
    GPIOB->ODR = color2;
    LCD_WRHigh();
}

void Write(uint8_t com, uint16_t par)
{
    if (com == 0)
    {
        wr_cmd_parall1_8(par);
    }
    else
    {
        wr_dat_parall1_8(par);
    }
}

void initial(void)
{
    LCD_RSTHigh();
    HAL_Delay(10); // ms
    LCD_RSTLow();
    HAL_Delay(10); // ms
    LCD_RSTHigh();
    HAL_Delay(10); // ms
    HAL_Delay(120);

//************* Start Initial Sequence **********//
	Write(Command, 0x11); //Exit Sleep
	HAL_Delay(120);

	Write(Command, 0xB1);//60HZ
    Write(Parameter,0x02);
    Write(Parameter,0x35);
    Write(Parameter,0x36);
	Write(Command, 0xB2);
    Write(Parameter,0x02);
    Write(Parameter,0x35);
    Write(Parameter,0x36);
	Write(Command, 0xB3);
    Write(Parameter,0x02);
    Write(Parameter,0x35);
    Write(Parameter,0x36);
    Write(Parameter,0x02);
    Write(Parameter,0x35);
    Write(Parameter,0x36);
	Write(Command, 0xB4);
    Write(Parameter,0x03);	  //

	Write(Command, 0xC0); //
    Write(Parameter,0xA2);
    Write(Parameter,0x02);
    Write(Parameter,0x84);
	Write(Command, 0xC1); //
    Write(Parameter,0xc5);
	Write(Command, 0xC2); //
    Write(Parameter,0x0d);
    Write(Parameter,0x00);
	Write(Command, 0xC3); //
    Write(Parameter,0x8D);
    Write(Parameter,0x2A);
	Write(Command, 0xC4); //
    Write(Parameter,0x8D);
    Write(Parameter,0xee);
	Write(Command, 0xC5); //
    Write(Parameter,0x03);

    Write(Command, 0x36); //memory data access
    Write(Parameter,0xc8);	   //MX=0,MY=0	 RGB ͬ 100N

    Write(Command, 0xE0); //gai
    Write(Parameter,0x12);//p1
    Write(Parameter,0x1C);//p2
    Write(Parameter,0x10);//p3
    Write(Parameter,0x18);//p4
    Write(Parameter,0x33);//p5
    Write(Parameter,0x2C);//p6  
    Write(Parameter,0x25);//p7
    Write(Parameter,0x28);//p8
    Write(Parameter,0x28);//p9
    Write(Parameter,0x27);//p10
    Write(Parameter,0x2F);//p11
    Write(Parameter,0x3C);//p12
    Write(Parameter,0x00);//p13
    Write(Parameter,0x03);//p14
    Write(Parameter,0x03);//p15
    Write(Parameter,0x10);//p15

    Write(Command, 0xE1); //gai
    Write(Parameter,0x12);//p1
    Write(Parameter,0x1c);//p2
    Write(Parameter,0x10);//p3
    Write(Parameter,0x18);//p4
    Write(Parameter,0x2D);//p5
    Write(Parameter,0x28);//p6  
    Write(Parameter,0x23);//p7
    Write(Parameter,0x28);//p8
    Write(Parameter,0x28);//p9
    Write(Parameter,0x26);//p10
    Write(Parameter,0x2F);//p11
    Write(Parameter,0x3B);//p12
    Write(Parameter,0x00);//p13
    Write(Parameter,0x03);//p14
    Write(Parameter,0x03);//p15
    Write(Parameter,0x10);//p15

    Write(Command, 0x3A); //Set Color Format/interface pixel format
    Write(Parameter,0x06);	   //55  16 bit/pixel ,66 18 bit/pixel


    Write(Command, 0x2A); //Set Column Address
    Write(Parameter,0x00);
    Write(Parameter,0x00);	 //0X02
    Write(Parameter,0x00);
    Write(Parameter,0x7F);	 //0X81

    Write(Command, 0x2B); //Set Page Address
    Write(Parameter,0x00);
    Write(Parameter,0x00);	//0X03	ʵ����--132X162
    Write(Parameter,0x00);
    Write(Parameter,0x7F);	//0X82


	Write(Command, 0x29);	//Display On
	Write(Command, 0x2c);	//Memory write
//**********************************************************/

}

// void Filllcd_Area(uint16_t _usX, uint16_t _usY, uint16_t _usWidth , uint16_t _usHeight, uint16_t color)
void Filllcd_Area(uint32_t color)
{
    uint32_t x = 0;
    uint32_t y = 0;
    /*//显示区域限制
    wr_cmd_4spi_8bcs(GC9A01_CMD_CASETF);
    wr_dat_4spi_8bcs(_usX >> 8);
    wr_dat_4spi_8bcs(_usX );
    wr_dat_4spi_8bcs( (_usX + _usWidth - 1) >> 8);
    wr_dat_4spi_8bcs( (_usX + _usWidth - 1) );

    wr_cmd_4spi_8bcs(GC9A01_CMD_RASETF );
    wr_dat_4spi_8bcs(_usY >> 8);
    wr_dat_4spi_8bcs(_usY );
    wr_dat_4spi_8bcs( (_usY + _usHeight - 1) >> 8 );
    wr_dat_4spi_8bcs( (_usY + _usHeight - 1) );
    //准备接收数据*/
    /*wr_cmd_4spi_8bcs(0x2c);

    //uint8_t colorred = color >> 16;
    uint8_t color1 = (color & 0xff00) >> 8;
    uint8_t color2 = (color & 0xff);
    //uint8_t color1,color2;
    for( y=0; y < LCD_Height; y++ )
        {for( x=0; x < LCD_Width; x++ )
        {
            wr_dat_4spi_8bcs( 0xf8);
            wr_dat_4spi_8bcs( 0x00 );
        }
    }*/
    /*wr_c2c();

    for( y=0; y < LCD_Height ; y++ )
        {for( x=0; x < LCD_Width; x++ )
        {
            wr_num(0xf8);
            wr_num(0x00);
        }
    }*/
    wr_cmd_parall1_8(0x2a);
    wr_dat_parall1_8(0x00);
    wr_dat_parall1_8(0x00);
    wr_dat_parall1_8(0x00);
    wr_dat_parall1_8(0xef);

    wr_cmd_parall1_8(0x2b);
    wr_dat_parall1_8(0x00);
    wr_dat_parall1_8(0x00);
    wr_dat_parall1_8(0x01);
    wr_dat_parall1_8(0x3F);

    wr_cmd_parall1_8(0X2C);
    // uint8_t colorred = color >> 16;
    // uint8_t color1 = (color & 0xff00) >> 8;
    // uint8_t color2 = (color & 0xff);
    for (y = 0; y < 320; y++)
    {
        for (x = 0; x < 240; x++)
        {
            wr_displ_parall1_8(0xf8);
            wr_displ_parall1_8(0x00);
            wr_displ_parall1_8(0x00);
            /*wr_displ_parall1_8(colorred);
            wr_displ_parall1_8(color1);
            wr_displ_parall1_8(color2);	*/
            // wr_displ_parall2_18_H(0x0003);
            // wr_displ_parall2_18_L(0xF000);
        }
    }
}